<?php
/* 
 * $file = lib_file::instance();
 * or
 * $file = lib_file::instance(NULL,true);
 * or
 * $file = lib_file::instance(DOCROOT.'log.txt');
 * $file->write_line('one line');
 * $file->rename(time().'.txt');
 * echo $file->get();
 * var_dump($file->filename);
 * $file->del();
 * */
class lib_file{
	public $filename;
	
	private $readable;
	
	private $writable;
	
	private $autodel;
	
	public function __construct($filename = null,$autodel = false){
		if (is_file($filename)){
			$this->filename = realpath($filename);
			$this->readable = is_readable($this->filename);
			$this->writable = is_writable($this->filename);
		}elseif($file = fopen($filename,'a+')){
			$this->filename = realpath($filename);
			$this->readable = true;
			$this->writable = true;
		}else{
			$this->create_tmp() and print('cannot open file: '.$filename.', using template file: '.$this->filename.'<br />');
		}
	}
	
	public static function instance($filename = NULL,$autodel = false){
		return new self($filename,$autodel);
	}
	
	public function readable($filename){
		if ($this->readable)
			return true;
		if (!is_file($filename))
			return false;
		if (!is_readable($filename))
			@chmod ($filename,644);
		return $this->readable = is_readable($filename);
	}
	
	public function writable($filename){
		if ($this->writable)
			return true;
		if (!is_file($filename))
			return false;
		if (!is_writable($filename))
			@chmod ($filename,777);
		return $this->writable = is_writable($filename);
	}
	
	public function rename($newname){
		rename($this->filename,$newname) or die('rename '.$this->filename.' fail'.'<br />');
		$this->filename = $newname;
	}
	
	public function clear(){
		$file = fopen($this->filename,'w+b');
		fclose($file);
	}
	
	public function del(){
		unlink($this->filename) or die('delete '.$this->filename.' fail'.'<br />');
	}
	
	public function create_tmp($prefix = 'temp',$dir = '.'){
		$this->autodel = true;
		$this->filename = tempnam($dir,$prefix);
		($this->filename = realpath($this->filename)) or die('cannot create template file'.'<br />');
		$this->readable($this->filename) or die('cannot read template file: '.$this->filename.'<br />');
	}
	
	public function get(){
		$this->readable($this->filename) or die('cannot read file: '.$this->filename.'<br />');
		return file_get_contents($this->filename);
	}
	
	public function get_line(){
		$this->readable($this->filename) or die('cannot read file: '.$this->filename.'<br />');
		return file($this->filename);
	}
	
	public function write($string){
		$this->writable($this->filename) or die('cannot write file: '.$this->filename.'<br />');
		$file = fopen($this->filename,'a+b');
		fwrite($file,$string);
		fclose($file);
	}
	
	public function write_line($string){
		$this->writable($this->filename) or die('cannot write file: '.$this->filename.'<br />');
		$file = fopen($this->filename,'a+b');
		fwrite($file,$string."\n");
		fclose($file);
	}
	
	public function filesize(){
		$this->readable($this->filename) or die('cannot read file: '.$this->filename.'<br />');
		if ($file = fopen($this->filename,'rb')){
			$current = ftell($file);
			fseek($file, 0,SEEK_END);
			$filesize = ftell($file);
			fseek($file, $current);
			return $filesize;
		}
		return filesize($this->filename);
	}
	
	public function download(){
		$filesize = $this->filesize();
		$file = fopen($this->filename,'rb');
		header('Content-Type: application/octet-stream'); 
		header('Content-Disposition: attachment; filename='.basename($this->filename)); 
		header('Content-Transfer-Encoding: binary'); 
		header('Expires: 0'); 
		header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
		header('Pragma: public'); 
		header('Content-Length: ' . $filesize);
		ob_clean();
		flush();
		echo fread($file,$filesize);
	}
	
	public function __destruct(){
		if ($this->autodel) @unlink($this->filename);
	}
}